package com.atguigu.gmall.activity.receiver;

import com.atguigu.gmall.activity.mapper.SeckillGoodsMapper;
import com.atguigu.gmall.activity.util.CacheHelper;
import com.atguigu.gmall.activity.util.DateUtil;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.MD5;
import com.atguigu.gmall.model.activity.OrderRecode;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class ActivityReceiver {

    @Resource
    private SeckillGoodsMapper seckillGoodsMapper;

    @Resource
    private RedisTemplate redisTemplate;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_TASK_1,durable = "true",autoDelete = "false"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_TASK),
            key = MqConst.ROUTING_TASK_1))
    public void importDataToRedis(Message message, Channel channel){
        try {
            /*SELECT * FROM seckill_goods WHERE `status` = '1' AND stock_count > 0
            AND DATE_FORMAT(start_time,'%Y-%m-%d') = '2021-04-27'*/
            //查询秒杀商品
            //导入秒杀商品数据到Redis中
            QueryWrapper<SeckillGoods> queryWrapper = new QueryWrapper<>();
            //审核状态 0：未审核  1：审核通过
            queryWrapper.eq("status","1");
            //库存大于0
            queryWrapper.gt("stock_count",0);
            //开始时间//结束时间  现在是凌晨一点  只要在今天
            queryWrapper.eq("DATE_FORMAT(start_time,'%Y-%m-%d')", DateUtil.formatDate(new Date()));
            //1:查询秒杀商品数据
            List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectList(queryWrapper);
            //秒杀商品集合存在 放入缓存
            if (!CollectionUtils.isEmpty(seckillGoodsList)){
                seckillGoodsList.forEach(seckillGoods -> {
                    //保存缓存中
                    Long skuId = seckillGoods.getSkuId();
                    redisTemplate.opsForHash().put(RedisConst.SECKILL_GOODS, skuId.toString(),seckillGoods);
                    //根据每一款商品的数量  准备集合
                    Long[] skuIds = new Long[seckillGoods.getStockCount()];
                    for (Integer i = 0; i < seckillGoods.getStockCount(); i++) {
                        skuIds[i] = skuId;
                    }
                    redisTemplate.opsForList().leftPushAll(RedisConst.SECKILL_STOCK_PREFIX + skuId,skuIds);
                    //3:Redis发布、订阅模式
                    redisTemplate.convertAndSend("seckillpush",skuId+":1");
                });
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_SECKILL_USER,durable = "true",autoDelete = "true"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_SECKILL_USER),
            key = MqConst.ROUTING_SECKILL_USER))
    public void seckill(UserRecode userRecode, Message message, Channel channel){
        try {
            Long skuId = userRecode.getSkuId();
            String userId = userRecode.getUserId();
            String state = (String) CacheHelper.get(skuId.toString());
            //1://产品状态位， 1：可以秒杀 0：秒杀结束
            if("0".equals(state)){
                //已售罄
                return;
            }
            //2: //判断用户是否下单
            Boolean isExist = redisTemplate.opsForValue().setIfAbsent(RedisConst.SECKILL_USER +
                            userId, skuId,
                    RedisConst.SECKILL__TIMEOUT, TimeUnit.SECONDS);
            if(!isExist){
                //此用户已经买过了、不能再买了
                return;
            }
            //3: //获取队列中的商品，如果能够获取，则商品存在，可以下单
            String id = String.valueOf(redisTemplate.opsForList().rightPop(RedisConst.SECKILL_STOCK_PREFIX + skuId));
            if(id == null){
                //商品售罄，更新状态位
                redisTemplate.convertAndSend("seckillpush", skuId + ":0");
                return;
            }
            //4：可以下单了
            OrderRecode orderRecode = new OrderRecode();
            orderRecode.setUserId(userId);
            orderRecode.setNum(1);
            SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.opsForHash()
                    .get(RedisConst.SECKILL_GOODS, skuId.toString());
            orderRecode.setSeckillGoods(seckillGoods);
            orderRecode.setOrderStr(MD5.encrypt(userId + skuId));
            //保存预订单
            redisTemplate.opsForValue().set(RedisConst.SECKILL_ORDERS + userId,orderRecode);

            //更新商品的库存
            //this.updateStockCount(skuId);
            //应答
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
